using Microsoft.SharePoint.WebPartPages;
using System;
using System.ComponentModel;
using System.Web.Caching;
using System.Web.UI;
using System.Xml.Serialization;
using ThoughtWorks.CruiseControl.Remote;


namespace TamTam.SharePoint.CruiseControl {

    [XmlRoot(Namespace = "TamTam.SharePoint.CruiseControl"), 
    ToolboxData("<{0}:CruiseControlProjectInfo runat=server></{0}:CruiseControlProjectInfo>"), 
    DefaultProperty("Text")]
	public class CCProjectInfo : WebPart {

		private string error=null;
		
        public CCProjectInfo() {
			this.server = "";
			this.project = "";
		}

		protected ProjectStatus GetProjectInfo() {
			ProjectStatus status1 = null;
			ICruiseManager man = null;
			string cacheKey = this.Server + "_" + this.Project;
			try {
				status1 = this.Page.Cache[cacheKey ] as ProjectStatus;
				if (status1 != null) {
					return status1;
				}
                string remotingurl = string.Format("tcp://{0}:{1}/CruiseManager.rem", this.Server, this.Port);

				RemotingServiceAdapter rsa = new RemotingServiceAdapter();
				
				man = (ICruiseManager )rsa.Connect(typeof(ICruiseManager), remotingurl);
			}
			catch(Exception exc){
				status1 = null;
				error = "1:" + exc.Message;
				if ( exc.InnerException != null )
					error += "<br />" + exc.InnerException.Message;
			}
			try{
				ProjectStatus[] statusArray1 = man.GetProjectStatus();
				foreach (ProjectStatus status2 in statusArray1) {
					if (string.Compare(status2.Name,this.Project,true)==0) {
						status1 = status2;
					}
				}
				if (status1 != null) {
					this.Page.Cache.Add(cacheKey , status1, null, DateTime.Now.AddMinutes(2), new TimeSpan((long) 0), CacheItemPriority.BelowNormal, null);
				}
			}
			catch(Exception exc){
				status1 = null;
				error = "2:" +  exc.Message;
				if ( exc.InnerException != null )
					error += "<br />" + exc.InnerException.Message;
			}
			return status1;
		}

		protected override void RenderWebPart(HtmlTextWriter output) {
			output.Write("<style>th{ text-align:left; font-weigth:bold; } span.success{ color:#10dF10 !important; } span.failure{ color:#DF1010 !important;} span.exception{ color:#DF1010 !important; }</style>");
			ProjectStatus status1 = this.GetProjectInfo();
			if (status1 != null) {
				output.Write("<table width=\"100%\">");
				output.Write("<tr>");
				output.Write("<th colspan=2>");
				output.Write("<img src=\"/applications/images/visualstudio.gif\" alt=\"VisualStudio\"/>");
				output.Write("&nbsp;Tam Tam BuildLab");
				output.Write("</th>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("BuildLab:");
				output.Write("</td>");
				output.Write("<td>");
				output.Write(this.Server);
				output.Write("</td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Project:");
				output.Write("</td>");
				output.Write("<td><a href=\"");
				output.Write(status1.WebURL);
				output.Write("\" target=\"_blank\">");
				output.Write(this.Project);
				output.Write("</a></td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<th colspan=2>");
				output.Write("Laatste build:");
				output.Write("</th>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Label");
				output.Write("</td>");
				output.Write("<td>");
				output.Write(status1.LastBuildLabel);
				output.Write("</td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Datum:");
				output.Write("</td>");
				output.Write("<td>");
				output.Write(status1.LastBuildDate.ToString("dd-MM-yyyy HH:mm"));
				output.Write("</td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Status:");
				output.Write("</td>");
				output.Write("<td><span class=\"");
				output.Write(status1.BuildStatus.ToString().ToLower());
				output.Write("\">");
				output.Write(status1.BuildStatus.ToString());
				output.Write("</span></td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<th colspan=2>");
				output.Write("Laatste succesvolle build");
				output.Write("</th>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Label:");
				output.Write("</td>");
				output.Write("<td>");
				output.Write(status1.LastSuccessfulBuildLabel);
				output.Write("</td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<th colspan=2>");
				output.Write("Status");
				output.Write("</th>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Builder:");
				output.Write("</td>");
				output.Write("<td>");
				output.Write(status1.Activity.ToString());
				output.Write("</td>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<th colspan=2>");
				output.Write("Next");
				output.Write("</th>");
				output.Write("</tr>");
				output.Write("<tr>");
				output.Write("<td>");
				output.Write("Date:");
				output.Write("</td>");
				output.Write("<td>");
				output.Write(status1.NextBuildTime.ToString("dd-MM-yyyy HH:mm"));
				output.Write("</td>");
				output.Write("</tr>");
				output.Write("</table>");
			}
			else {
				output.Write("<table><tr><td>Please select project first.");
				if ( this.error  != null ) {
					output.Write("<br />");
					output.Write(this.error);
				}
				output.Write("</td></tr></table>");

			}
		}


        [FriendlyName("Project"), WebPartStorage(Storage.Shared), Description("Projectname from the CruiseControl installation"), Browsable(true), Category("CruiseControl")]
		public string Project {
			get {
				return this.project;
			}
			set {
				this.project = value;
			}
		}

        [FriendlyName("Server"), Browsable(true), Category("CruiseControl"), WebPartStorage(Storage.Shared), Description("CruiseControl server")]
		public string Server {
			get {
				return this.server;
			}
			set {
				this.server = value;
			}
		}

        private int portnumber = 21234;

        /// <summary>
        /// The portnumber to communicate with cruisecontrol
        /// </summary>
        /// <remarks>default is 21234</remarks>
        [Description("CruiseControl serverport"),
        Browsable(true),
       Category("CruiseControl"),
        WebPartStorage(Storage.Shared),
       FriendlyName("Port")]
        public int Port {
            get {
                return this.portnumber;
            }
            set {
                if (value == 0)
                    this.portnumber = 21234;
                else
                    this.portnumber = value;
            }
        }

		private string project;
		private string server;
	}
}